home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / berm122 / pack.c < prev    next >
C/C++ Source or Header  |  1993-08-16  |  55KB  |  2,018 lines

  1. /**************************************************************************
  2.  *  PACK.C                                                                *
  3.  *                                                                        *
  4.  * Message bundler for use with The-Box/Pandora/QBBS-ST type messagebase  *
  5.  *                                                                        *
  6.  * PACK is part of the BERMUDA software. BERMUDA is a package of FidoNet  *
  7.  * compatible message/nodelist processing software.                       *
  8.  * Please read LICENSE for information about distribution.                *
  9.  *                                                                        *
  10.  * Written by Jac Kersing,                                                *
  11.  * Modifications by Arjen Lentz and Enno Borgsteede                       *
  12.  * Modifications by Vincent Pomey and Franck Arnaud                       *
  13.  **************************************************************************/
  14.  
  15. #define MAXMSGLEN (30 * 1024)   /* Don't increase it too much or PC's
  16.                                  * won't like it!!
  17.                                  */
  18.  
  19. #define MAILER              /* needed in PANDORA.H */
  20.  
  21. #include "pandora.h"        /* for structure of the area's etc. */
  22. #include <string.h>
  23.  
  24. #if TC
  25. #include <dos.h>
  26. #endif
  27.  
  28. #if STTC
  29. #ifdef LINN
  30. #include <tos.h>    /* Dcreate for bibi */
  31. #endif
  32. #endif
  33.  
  34. #include "mail.h"           /* pretty obvious if your packing mail.. */
  35.  
  36. #include "pack.pro"
  37. #include "route.pro"
  38. #include "utextra.pro"
  39.  
  40. #define UVERSION "1.22"  /* version-number */
  41. #define isBERMUDA 0xA0       /* productcode for BERMUDA */
  42.  
  43. #define DEBUG    0           /* show debugging info? */
  44.  
  45. #ifdef  ERROR
  46. #undef  ERROR
  47. #endif
  48.  
  49. struct _passw           /* structure for passwords */
  50. {
  51.   char passw[8];        /* the password itself */
  52.   int  zone;            /* zone number for remote */
  53.   int  net;             /* net number for remote */
  54.   int  node;            /* node number for remote */
  55.   int  point;           /* point number for remote */
  56.   int  my_aka;          /* the number in the addresslist for this sucker */
  57.   struct _passw *next;  /* pointer to next struct */
  58. } ;
  59.  
  60. struct _aka
  61. {
  62.  int zone;
  63.  int net;
  64.  int node;
  65.  int point;
  66.  int pointnet;
  67. } ;
  68.  
  69. char progname[]="B-P";      /* program name for logging */
  70. FILE *fopen(), *pkt;        /* the mailpacket */
  71. char *Bpath="";             /* path for mailer info */
  72.  
  73. struct _pkthdr phdr;        /* storage for packetheader */
  74. struct _pktmsgs mhdr;       /* header of current message */
  75. struct Hdr Mhdr;            /* storage for outgoing message header  */
  76. struct Hdr Shdr;            /* save message header */
  77.  
  78. char arc_prg[90];           /* archive program name */
  79. char arc_cmd[90];           /* commands for archive program */
  80. #ifdef LINN
  81. #define ARC 0
  82. #define ZIP 1
  83. #define ZOO 2
  84. #define LZH 3
  85. #define ARJ 4
  86. char archiv_prg[5][90];
  87. char archiv_cmd[5][90];
  88. int  binkley=0;
  89. #endif
  90.  
  91. char *hold;                 /* path to hold area                    */
  92. #ifdef LINN
  93. char *holdbink;             /* same but without trailing /          */
  94. int  addintl=0;                /* always add intl lines in netmail        */
  95. #endif
  96. char *mailpath;             /* path to netmail                      */
  97. char *netpath;              /* path to netmsgs                      */
  98. struct _aka alias[30];      /* aliases                              */
  99. int  nalias;                /* number of aliases                    */
  100. int  verbose=6;             /* level for message displaying         */
  101. int  loglevel;              /* level for message logging            */
  102. char *logname;              /* name of logfile                      */
  103. FILE *log;                  /* filepointer for logfile              */
  104. struct _passw *pwd;         /* password pointer                     */
  105.  
  106. int  ourzone;               /* zone,                                */
  107. int  ournet;                /*      net and                         */
  108. int  ournode;               /*              node of our BBS         */
  109. int  ourpoint;              /*                 point                */
  110. int  ourpointnet;           /* we've got a pointnet too             */
  111. char ourpwd[10];            /* the password we're using now         */
  112.  
  113. char active[20];            /* the active if                        */
  114.  
  115. char *MESSAGE;              /* adress of message buffer (malloced)  */
  116.  
  117. FILE *MHDR;
  118. FILE *MMSG;
  119.  
  120. int  pktzone[10];           /* zone, net, node                      */
  121. int  pktnet[10];            /* = address for open packet            */
  122. int  pktnode[10];           /* used for saving messages to          */
  123. int  pkttype[10];           /* type of packet (Crash/Hold/Normal)   */
  124. FILE *pktfile[10];          /* the packet                           */
  125.  
  126. char *pktnames[1000];
  127.  
  128. #ifdef LINN
  129. char binktype(char in);
  130. char *convert (char *name);
  131. int hextoint (char *str, int len);
  132. char *ffirstout(char *name);
  133. char *fnextout(void);
  134.  
  135. /* converts the The-Box letter for mail type to Binkley */
  136. char binktype(char in)
  137. {
  138.     switch(in)
  139.     {
  140.         case 'W':    /* hold */
  141.         case 'H':
  142.         return 'H';
  143.         
  144.         case 'I': /* crash /direct ? */
  145.         case 'C':
  146.         return 'C';
  147.  
  148.         case 'P': /* poll files */
  149.         case 'A': /* along doesn't exist with bink */
  150.         case 'N': /* normal */
  151.         return 'O';
  152.  
  153.     }
  154.     message (6, "!Mhhhmm, I'm buggy");
  155.     return 'H';
  156. }
  157.  
  158. char boxtype(char in)
  159. {
  160.     switch(in)
  161.     {
  162.         case 'H':
  163.         return 'W';
  164.         
  165.         case 'D':
  166.         case 'C':
  167.         return 'C';
  168.         
  169.         case 'O':
  170.         return 'N';
  171.         
  172.         case 'F': /* poll files */
  173.         return 'P';
  174.  
  175.     }
  176.     message (6, "!Mhhhmm, I'm buggy");
  177.     return 'W';
  178. }
  179.  
  180. /* simulate ffirst/fnext on a Binkley outbound */
  181. /* depends highly on the way they are used ! */
  182. /*  ie:calls with hold/*.?t where t is the mail type */
  183. /*  and uses only the names to find out the zone/net/node */
  184.  
  185. char fouttype, foutflav;    /* the type and flavor of mail beeing scanned */
  186. char foutname[100];        /* the name returned, in The-Box format */
  187. int  numscanzone, curzone;    /* number of zones already scanned */
  188.  
  189. /* converts a Binkley file name to a The-Box filename, using curzone */
  190. char *convert (char *name)
  191. {
  192.     int net, node, point;
  193.  
  194.     if (name==NULL)
  195.         return NULL;
  196.     net=ztoi (name, 3);
  197.     node=ztoi (name+3, 3);
  198.     point=ztoi (name+6, 2);
  199.     if (point)
  200.         return fnextout();
  201.     sprint (foutname, "%02z%03z%03z.%c%c", curzone, net, node, boxtype(name[9]), (name[10]=='P') ? 'M' : name[10]);
  202.     return foutname;
  203. }
  204.  
  205. int hextoint (char *str, int len)
  206. {
  207.     int temp;
  208.     
  209.     temp = 0;
  210.     while(*str && len-- && isalnum(*str))
  211.     {
  212.         temp *= 16;
  213.         temp += isdigit(*str) ? *str-'0' : toupper(*str)-'A'+10;
  214.         str++;
  215.     }
  216.     return temp;
  217. }
  218.  
  219. char *ffirstout(char *name)
  220. {
  221.     char tmp[100], *res;
  222.     
  223.     if (!binkley)
  224.         return ffirst (name);
  225.     numscanzone=0;
  226.     fouttype=(name[strlen(name)-1]=='M') ? 'P' : name[strlen(name)-1];
  227.     foutflav=(name[strlen(name)-2]=='?') ? '?' : binktype(name[strlen(name)-2]);
  228.     /* first, scan the main zone */
  229.     curzone=alias[0].zone;
  230.     sprintf (tmp, "%s*.%c%cT", hold, foutflav, fouttype);
  231.     res=ffirst(tmp);
  232.     if (res==NULL)
  233.         return fnextout();
  234.     else    return convert(res);
  235. }
  236.  
  237. char *fnextout()
  238. {
  239.     char *res, tmp[100];
  240.     int i;
  241.     
  242.     if (!binkley)
  243.         return fnext();
  244.     res=fnext();
  245.     if (res==NULL) {
  246.         /* end of zone directory scan, go to the next zone */
  247.         sprintf (tmp, "%s.???", holdbink);
  248.         i=numscanzone;
  249.         res=ffirst (tmp);
  250.         while (i--)
  251.             res=fnext();    /* skip the directory already scanned */
  252.         if (res==NULL)
  253.             return NULL;
  254.         numscanzone++;
  255.         curzone=hextoint (res+strlen(res)-3, 3);
  256.         sprint (tmp, "%s.%03y%c*.%c%cT", holdbink, curzone, DIRSEP, foutflav, fouttype);
  257.         return convert (ffirst (tmp));
  258.     }
  259.     else return convert (res);
  260. }
  261. #endif
  262.  
  263. /* Ok, so far all definitions. The program is next.. */
  264.  
  265. char *skip_blanks(string)
  266. char *string;
  267. {
  268.     while (*string && isspace(*string)) ++string;
  269.     return string;
  270. }
  271.  
  272. char *skip_to_blank(string)
  273. char *string;
  274. {
  275.         while (*string && !isspace(*string)) ++string;
  276.         return string;
  277. }
  278.  
  279. char *myalloc(sp)
  280. size_t sp;
  281. {
  282.     char *tmp;
  283.     
  284.     tmp=malloc(sp);
  285.     if (tmp==NULL)
  286.     {
  287.         message(6,"!Mem error");
  288.         exit(1);
  289.     }
  290.     return tmp;
  291. }
  292.  
  293. char *ctl_string(string)
  294. char *string;
  295. {
  296.     char *p, *d;
  297.     p=skip_blanks(string);
  298.     d=myalloc(strlen(p)+1);
  299.     strcpy(d,p);
  300.     return d;
  301. }
  302.  
  303. char *ctl_path(str)
  304. char *str;
  305. {
  306.     char *q;
  307.     
  308.     str= skip_blanks(str);
  309.     for (q=str; *q && !isspace(*q); q++) ;
  310.     *q= '\0';
  311. #if UNIX
  312.     if (*(q-1)!='/') strcat(q,"/");
  313. #else
  314.     if (*(q-1)!='\\') strcat(q,"\\");
  315. #endif
  316.     return ctl_string(str);
  317. }
  318.  
  319. char *ctl_file(str)
  320. char *str;
  321. {
  322.     char *q;
  323.     
  324.     str= skip_blanks(str);
  325.     for (q=str; *q && !isspace(*q); q++) ;
  326.     *q= '\0';
  327.     return ctl_string(str);
  328. }
  329.  
  330. int init_conf()
  331. {
  332.     FILE *conf;                     /* filepointer for config-file */
  333.     char buffer[256];               /* buffer for 1 line */
  334.     char *p;                        /* workhorse */
  335. #ifdef LINN
  336.      char *q;
  337. #endif
  338.     int count;                      /* just a counter... */
  339.     char *getenv();                 /* get the environment string */
  340.  
  341.     /* Try to find the path for configuration */
  342.     
  343.     p=getenv("MAILER");
  344.     if (!ffirst("bermuda.cfg") &&      /* check local config */
  345.         !ffirst("tb.cfg") &&
  346.         p!=NULL && *p!='\0')
  347.     {                                   /* no local, and envi contained one */
  348.         Bpath= ctl_path(p);
  349.     }
  350.  
  351.     /* set all to default values */
  352.     
  353.     loglevel=255;
  354.     ourzone=ournet=ournode=ourpoint=0;
  355.  
  356.     sprintf( buffer, "%sbermuda.cfg", Bpath);
  357.     conf= fopen(buffer, "r");
  358.  
  359.     if (conf==NULL)
  360.     {
  361.         sprintf(buffer,"%stb.cfg", Bpath);
  362.  
  363.         conf = fopen(buffer, "r");
  364.     }
  365.  
  366.     if (conf==NULL)
  367.     {
  368.         message(6,"!Configuration file not found, please check!!!");
  369.         return 1;                           /* not found, back */
  370.     }
  371.  
  372.     message(-1,"+Parsing configuration file");
  373.        
  374.     while((fgets(buffer, 250, conf)))       /* read a line */
  375.     {
  376.         p=skip_blanks(buffer);
  377.         if (*p==';') continue;               /* comment?? */
  378.  
  379.         /* delete ALL chars following (and inclusive) after comment sign */
  380.         if ((p=strchr(buffer,';'))!=NULL)  *p= '\0';
  381.         if ((count= (int)strlen(buffer))<3) continue;
  382.                                             /* what's the length of the rest? */
  383.         p= &buffer[--count];
  384.         if (*p=='\n') *p=0;                 /* delete (possible) newline char */
  385.  
  386. #ifdef LINN
  387.         /* process "application bermuda" lines as normal lines */
  388.         if (!strnicmp(buffer,"application",11))
  389.         {
  390.             p=skip_blanks(&buffer[11]);
  391.             if(!strnicmp(p,"bermuda",7)) {
  392.                 p=skip_blanks(&p[7]);
  393.                 strcpy (buffer, p);
  394.             }
  395.         }
  396. #endif
  397.         if (!strnicmp(buffer,"address",7))
  398.         {
  399.             p=skip_blanks(&buffer[7]);
  400.             if(getaddress(p,&alias[nalias].zone, &alias[nalias].net,
  401.                 &alias[nalias].node, &alias[nalias].point)!=7)
  402.             {
  403.                message(3,"!Invalid address in %s",buffer);
  404.                continue;
  405.             }
  406.             p=skip_blanks(skip_to_blank(p));
  407.  
  408.             if (*p=='+' || *p=='*') p=skip_blanks(skip_to_blank(p));
  409.  
  410.             if (*p && isdigit(*p))
  411.             {
  412.                 if ((alias[nalias].pointnet=atoi(p))==0)
  413.                 {
  414.                    message(6,"!Invalid pointnet in %s",buffer);
  415.                    continue;
  416.                 }
  417.             }
  418.             else alias[nalias].pointnet=0;
  419.             ++nalias;
  420.  
  421.             ourzone=alias[0].zone;
  422.             ournet=alias[0].net;
  423.             ournode=alias[0].node;
  424.             ourpoint=alias[0].point;
  425.             ourpointnet=alias[0].pointnet;
  426.  
  427.             continue;
  428.         }
  429.  
  430.         if (!strnicmp(buffer,"loglevel",8))
  431.         {
  432.             p=skip_blanks(&buffer[8]);
  433.             if (sscanf(p,"%d", &count)!=1 || count>6 || count<0)
  434.                 message(3,"-Invalid loglevel (%s)", p);
  435.             else loglevel=count;
  436.             continue;
  437.         }
  438.  
  439.         if (!strnicmp(buffer, "statuslog",9))
  440.         {
  441.             logname= ctl_string(&buffer[9]);
  442.             if ((log=fopen(logname, "a"))==NULL)
  443.                 if ((log=fopen(logname, "w+"))==NULL)
  444.                 {
  445.                     message(6,"!Could not create logfile!");
  446.                     free(logname);
  447.                     logname=NULL;
  448.                 }
  449.             else
  450.             {
  451.                 fflush(log);
  452.             }
  453.             continue;
  454.         }
  455.  
  456.         if (!strnicmp(buffer,"netfile",7))
  457.         {
  458.             mailpath=ctl_path(&buffer[7]);
  459.             continue;
  460.         }
  461.  
  462.         if (!strnicmp(buffer,"netmail",7))
  463.         {
  464.             netpath=ctl_string(&buffer[7]);
  465.             continue;
  466.         }
  467.  
  468.         if (!strnicmp(buffer,"hold",4))
  469.         {
  470.             hold=ctl_path(&buffer[4]);
  471. #ifdef LINN
  472.             holdbink=strdup(hold); holdbink[strlen(holdbink)-1]=0;
  473. #endif
  474.             continue;
  475.         }
  476.  
  477.         if (!strnicmp(buffer,"key",3))
  478.         {
  479.             parsekey(&buffer[3]);
  480.             continue;
  481.         }
  482. #ifdef LINN
  483.     if (!strnicmp(buffer,"arcpack", 7))
  484.     {
  485.         p=skip_blanks(&buffer[7]);
  486.             q=p;
  487.             while (*q && !isspace(*q)) ++q;
  488.             *q='\0';
  489.         strcpy (archiv_prg[ARC], p);
  490.             p=skip_blanks(&p[strlen(p)+1]);    /* skip to next word */
  491.             strcpy (archiv_cmd[ARC], p);
  492.         continue;
  493.     }
  494.  
  495.     if (!strnicmp(buffer,"zippack", 7))
  496.     {
  497.         p=skip_blanks(&buffer[7]);
  498.             q=p;
  499.             while (*q && !isspace(*q)) ++q;
  500.             *q='\0';
  501.         strcpy (archiv_prg[ZIP], p);
  502.             p=skip_blanks(&p[strlen(p)+1]);    /* skip to next word */
  503.             strcpy (archiv_cmd[ZIP], p);
  504.         continue;
  505.     }
  506.  
  507.     if (!strnicmp(buffer,"zoopack", 7))
  508.     {
  509.         p=skip_blanks(&buffer[7]);
  510.             q=p;
  511.             while (*q && !isspace(*q)) ++q;
  512.             *q='\0';
  513.         strcpy (archiv_prg[ZOO], p);
  514.             p=skip_blanks(&p[strlen(p)+1]);    /* skip to next word */
  515.             strcpy (archiv_cmd[ZOO], p);
  516.         continue;
  517.     }
  518.  
  519.     if (!strnicmp(buffer,"lzhpack", 7))
  520.     {
  521.         p=skip_blanks(&buffer[7]);
  522.             q=p;
  523.             while (*q && !isspace(*q)) ++q;
  524.             *q='\0';
  525.         strcpy (archiv_prg[LZH], p);
  526.             p=skip_blanks(&p[strlen(p)+1]);    /* skip to next word */
  527.             strcpy (archiv_cmd[LZH], p);
  528.         continue;
  529.     }
  530.  
  531.     if (!strnicmp(buffer,"arjpack", 7))
  532.     {
  533.         p=skip_blanks(&buffer[7]);
  534.             q=p;
  535.             while (*q && !isspace(*q)) ++q;
  536.             *q='\0';
  537.         strcpy (archiv_prg[ARJ], p);
  538.             p=skip_blanks(&p[strlen(p)+1]);    /* skip to next word */
  539.             strcpy (archiv_cmd[ARJ], p);
  540.         continue;
  541.     }
  542.     if (!strnicmp(buffer,"binkley", 7))
  543.     {
  544.         binkley=1;
  545.         continue;
  546.     }
  547. #endif
  548.     }
  549.     
  550.     fclose(conf);
  551.     
  552.     return 0;                           /* signal OK */
  553. }
  554.  
  555. void parsekey(p)
  556. char *p;
  557. {
  558.     int i;
  559.     char password[9];
  560.     struct _passw *pw,*pn;
  561.     int zone,net,node,point;
  562.     int my_aka=0;
  563.     
  564.     /* get to the end of the list. */
  565.     pw=pwd;
  566.     while (pw->next!=NULL) pw=pw->next;
  567.  
  568.     password[0]='\0';
  569.     
  570.     p=skip_blanks(p);
  571.     while (*p && *p!=';')
  572.     {
  573.         if (*p=='!')
  574.         {
  575.             strncpy(password,p+1,7);
  576.             for (i=0; i<7; ++i)
  577.             {
  578.                 if (isspace(password[i])) break;
  579.             }
  580.             password[i]='\0';
  581.  
  582.             /* skip password and go on to node(s) */
  583.             p=skip_to_blank(p);
  584.             p=skip_blanks(p);
  585.             continue;
  586.         }
  587.  
  588.         if (*p=='#')
  589.         {
  590.             if (getaddress(p+1,&zone,&net,&node,&point))
  591.             {
  592.                 int found=0;
  593.                 for (i=0; i<nalias; i++)
  594.                 {
  595.                     if (alias[i].zone==zone && alias[i].net==net &&
  596.                         alias[i].node==node && alias[i].point==point)
  597.                     {
  598.                         found++;
  599.                         break;
  600.                     }
  601.                 }
  602.                 if (found) my_aka=i;
  603.                 else
  604.                 {
  605.                     my_aka=0;
  606.                     message(3,"-Address %d:%d/%d.%d used in key is unknown",
  607.                      zone,net,node,point);
  608.                 }
  609.             }
  610.  
  611.             p= skip_to_blank(p);
  612.             p= skip_blanks(p);
  613.             continue;
  614.         }
  615.  
  616.         pn=pw->next= (struct _passw *) myalloc(sizeof(struct _passw));
  617.  
  618.         if (!getaddress(p,&zone,&net,&node,&point))
  619.         {
  620.             free(pn);
  621.             pw->next=NULL;
  622.             message(3,"-Invalid address: %s",p);
  623.             return;
  624.         }
  625.  
  626.         if (point)
  627.         {
  628.             for (i=0; i < nalias; i++)
  629.             {
  630.                 if (alias[i].zone==zone && alias[i].net==net &&
  631.                     alias[i].node==node)
  632.                 {
  633.                     net= alias[i].pointnet;
  634.                     node= point;
  635.                     point= 0;
  636.                     break;
  637.                 }
  638.             }
  639.         }
  640.  
  641.         pn->zone=zone;
  642.         pn->net=net;
  643.         pn->node=node;
  644.         pn->point=point;
  645.         pn->my_aka=my_aka;
  646.         strcpy(pn->passw,password);
  647.         p=skip_to_blank(p);
  648.         p=skip_blanks(p);
  649.         pw=pn;
  650.         pw->next=NULL;
  651.     }
  652.     
  653.     return;
  654. }
  655.  
  656. int getint(p,i)                                   /* Mind the calling parms! */
  657. char **p;
  658. int *i;
  659. {
  660.         char *q;
  661.         long temp;
  662.  
  663.         q=*p;
  664.         if (!isdigit(*q)) return (-1);
  665.  
  666.         temp=0;
  667.         do {
  668.            temp*=10;
  669.            temp+=(*q++-'0');
  670.            } while (isdigit(*q));
  671.         if (temp>32767) return (-1);
  672.         *p=q; *i=(int) temp;
  673.         return (0);
  674. }
  675.  
  676. int getaddress(str, zone, net, node, point)     /* Decode zz:nn/mm.pp number */
  677. char *str;       /* 0=error | 1=node | 2=net/node | 3=zone:net/node | 4=pnt */
  678. int *zone, *net, *node, *point;
  679. {
  680.         int retcode=0;
  681.  
  682.         *zone  = alias[0].zone;
  683.         *net   = alias[0].net;
  684.         *node  = alias[0].node;
  685.         *point = 0;
  686.  
  687.         str=skip_blanks(str);
  688.  
  689.         if (*str=='.') goto pnt;
  690.         retcode++;
  691.         if (getint(&str,node))
  692.         {
  693.             if (strnicmp(str,"ALL",3)) return (0);
  694.             *zone=*net=*node=-1;
  695.             return 10;
  696.         }
  697.         if (!*str) return (retcode);
  698.         if (*str=='.') goto pnt;
  699.         retcode++;
  700.         if (*str==':') {
  701.            str++;
  702.            *zone=*node;
  703.            *node=-1;
  704.            if (!*str) return (0);
  705.            if (getint(&str,node))
  706.            {
  707.               if (strnicmp(str,"ALL",3)) return (0);
  708.               *net=*node=-1;
  709.               return 10;
  710.            }
  711.            retcode++;
  712.         }
  713.         if (*str!='/') return (0);
  714.         str++;
  715.         *net=*node;
  716.         *node=alias[0].node;
  717.         if (getint(&str,node))
  718.         {
  719.             if (strnicmp(str,"ALL",3)) return (0);
  720.             *node=-1;
  721.             return 10;
  722.         }
  723.         if (*str=='.') goto pnt;
  724.         return (retcode);
  725. pnt:    str++;
  726.         if (getint(&str,point))
  727.         {
  728.             if (strnicmp(str,"ALL",3)) return (0);
  729.             *point=-1;
  730.             return 10;
  731.         }
  732.         return (4+retcode);
  733. }
  734.  
  735. int getalias(zone,net,node,point)
  736. int zone,net,node,point;
  737. {
  738.     int i;
  739.     struct _passw *pw;
  740.     
  741.     pw=pwd->next;
  742.     
  743.     if (point)
  744.     {
  745.         for (i=0; i < nalias; i++)
  746.         {
  747.             if (alias[i].zone==zone && alias[i].net==net &&
  748.                alias[i].node==node && alias[i].point==0)
  749.             {
  750.                 net= alias[i].pointnet;
  751.                 node= point;
  752.                 point= 0;
  753.                 break;
  754.             }
  755.         }
  756.     }
  757.  
  758.     while (pw!=NULL)
  759.     {
  760.        /* no match at all.. (yet) */
  761.         if ((pw->zone==-1 || pw->zone==zone) &&
  762.        /* zone numbers match, now net */
  763.            (pw->net==-1 || pw->net==net) &&
  764.        /* zone and net match.. node also? */
  765.            (pw->node==-1 || pw->node==node) &&
  766.        /* and how about point */
  767.            (pw->point==-1 || pw->point==point))
  768.         {
  769.                 ourzone=alias[pw->my_aka].zone;
  770.                 ournet=alias[pw->my_aka].net;
  771.                 ournode=alias[pw->my_aka].node;
  772.                 ourpoint=alias[pw->my_aka].point;
  773.                 ourpointnet=alias[pw->my_aka].pointnet;
  774.                 return 1;
  775.         }
  776.         pw=pw->next;
  777.     }
  778.     ourzone=alias[0].zone;
  779.     ournet=alias[0].net;
  780.     ournode=alias[0].node;
  781.     ourpoint=alias[0].point;
  782.     ourpointnet=alias[0].pointnet;
  783.     return 0;
  784. }
  785.  
  786. void get_passw(zone,net,node,point)
  787. int zone,net,node,point;
  788. {
  789.     int i;
  790.     struct _passw *pw;
  791.     
  792.     pw=pwd->next;
  793.     
  794.     if (point)
  795.     {
  796.         for (i=0; i < nalias; i++)
  797.         {
  798.             if (alias[i].zone==zone && alias[i].net==net &&
  799.                 alias[i].node==node && alias[i].point==0)
  800.             {
  801.                 net= alias[i].pointnet;
  802.                 node= point;
  803.                 point= 0;
  804.                 break;
  805.             }
  806.         }
  807.     }
  808.  
  809.     while (pw!=NULL)
  810.     {
  811.        /* no match at all.. (yet) */
  812.         if ((pw->zone==-1 || pw->zone==zone) &&
  813.        /* zone numbers match, now net */
  814.            (pw->net==-1 || pw->net==net) &&
  815.        /* zone and net match.. node also? */
  816.            (pw->node==-1 || pw->node==node) &&
  817.        /* and how about point */
  818.            (pw->point==-1 || pw->point==point))
  819.         {
  820.                 strcpy(ourpwd,pw->passw);
  821.                 return;
  822.         }
  823.         pw=pw->next;
  824.     }
  825.     *ourpwd= '\0';
  826. }
  827.  
  828. void Init(argc, argv)       /* initialize everything needed */
  829. int argc;                   /* counter */
  830. char *argv[];               /* commandline crap */
  831. {
  832.     int  i;                 /* counter */
  833.     int  the_box=0;         /* flags to signal we wanna use logging */
  834.  
  835. #ifdef LINN
  836.     archiv_prg[ARC][0] = '\0';
  837.     archiv_prg[ZIP][0] = '\0';
  838.     archiv_prg[ZOO][0] = '\0';
  839.     archiv_prg[LZH][0] = '\0';
  840.     archiv_prg[ARJ][0] = '\0';
  841. #endif
  842. #if     MEGAMAX | MWC | STTC
  843.     strcpy(arc_prg,"ARC.TTP");
  844. #endif
  845. #if     TC
  846.     strcpy(arc_prg,"ARC.EXE");
  847. #endif
  848.     strcpy(arc_cmd,"M");
  849.  
  850.     pwd= (struct _passw *) myalloc(sizeof(struct _passw));
  851.     pwd->zone=pwd->net=pwd->node=pwd->point=0;
  852.     pwd->next=NULL;
  853.  
  854.     if (init_conf()) exit(2);       /* first parse config file */
  855.     
  856.     for (i=1;i<argc;i++)
  857.     {
  858.         if (argv[i][0]=='-')
  859.         {
  860.             switch(toupper(argv[i][1]))
  861.             {
  862.               case 'S': if (i+1< argc)
  863.                         {
  864.                             strncpy(active,argv[i+1],20);
  865.                             ++i;
  866.                             active[19]='\0';
  867.                         }
  868.                         break;
  869.               case 'T': ++the_box;      break;
  870.               case 'A': *arc_cmd= *arc_prg= '\0';
  871.                         if (i+1<argc)
  872.                         {
  873.                             strncpy(arc_prg,argv[i+1],89);
  874.                             i++;
  875.                             while (i<argc-1 &&
  876.                               (strlen(arc_cmd)+strlen(argv[i+1]))<88)
  877.                             {
  878.                                 strcat(arc_cmd,argv[i+1]);
  879.                                 strcat(arc_cmd," ");
  880.                                 i++;
  881.                             }
  882.                         }
  883.                         break;
  884.               case 'I': addintl++; break;
  885.               default : message(6,"!Unknown option %s",argv[0]);
  886.             }
  887.         }
  888.     }
  889.  
  890.     if (!netpath || !*netpath)
  891.     {
  892.         message(6,"!Don't know the path to your mailarea..");
  893.         exit(2);
  894.     }
  895.  
  896.     if (!the_box) loglevel=255;     /* called from command-line, no logging */
  897.  
  898.     if (loglevel<2) verbose=6;
  899. }
  900.  
  901. void OpenMail()
  902. {
  903.     char buffer[80];
  904.  
  905.     sprintf(buffer,"%s.MSG",netpath);
  906.     if((MMSG=fopen(buffer, BRUP))==NULL) MMSG=fopen(buffer, BWUP);
  907.     sprintf(buffer,"%s.HDR",netpath);
  908.     if((MHDR=fopen(buffer, BRUP))==NULL) MHDR=fopen(buffer, BWUP);
  909.     if (!MMSG || !MHDR)
  910.     {
  911.         message(6,"!Error opening Mailarea");
  912.         exit(1);
  913.     }
  914.  
  915.     if ((MESSAGE=malloc(MAXMSGLEN))==NULL)                            /* Agl */
  916.     {
  917.         message(6,"!Mem error");
  918.         exit(-39);
  919.     }
  920. }
  921.  
  922. void CloseMail()
  923. {
  924.         /* Close files and free memory used for message storage */
  925.         free(MESSAGE);
  926.         fclose(MHDR);
  927.         fclose(MMSG);
  928. }
  929.  
  930. void InitPackets()
  931. {
  932.         int i;
  933.  
  934.         for (i=0;i<10;i++)
  935.         {
  936.                 pktzone[i]= pktnet[i]= pktnode[i]= 0;
  937.                 pktfile[i]= NULL;
  938.         }
  939. }
  940.  
  941. void ClosePacket(nr)
  942. int nr;
  943. {
  944. #if DEBUG
  945. print("Close packet\n");
  946. #endif
  947.     if (pktfile[nr])
  948.     {
  949.         pktzone[nr]= pktnet[nr]= pktnode[nr]= 0;
  950.         if (fwrite("\0\0", 2, 1, pktfile[nr])!=1)
  951.         {
  952.             message(6,"!Error writing to packet");
  953.             exit(1);
  954.         }
  955.         fclose(pktfile[nr]);
  956.     }
  957. }
  958.  
  959. void DeInitPackets()
  960. {
  961.         int i;
  962.  
  963. #if DEBUG
  964. print("DeInit packets\n");
  965. #endif
  966.         for (i=0; i<10; i++)
  967.         {
  968.             if (pktzone[i]!=0 || pktnet[i]!=0 || pktnode[i]!=0)
  969.             {
  970.                 ClosePacket(i);
  971.             }
  972.         }
  973. }
  974.  
  975. int OurMessage(from)
  976. int from;
  977. {
  978.         int i;
  979.         int zone, net, node, point;
  980.  
  981.         /* Checks whether it's a message from/to one of our Aka's */
  982.         if (from)
  983.         {
  984.                 zone=Mhdr.Ozone;
  985.                 net= Mhdr.Onet;
  986.                 node= Mhdr.Onode;
  987.                 point= Mhdr.Opoint;
  988.         }
  989.         else
  990.         {
  991.                 zone= Mhdr.Dzone;
  992.                 net= Mhdr.Dnet;
  993.                 node= Mhdr.Dnode;
  994.                 point= Mhdr.Dpoint;
  995.         }
  996.  
  997.         for (i=0; i<nalias; i++)
  998.         {
  999.                 if (alias[i].zone==zone && alias[i].net==net &&
  1000.                     alias[i].node==node && alias[i].point==point) return 1;
  1001.         }
  1002. #ifdef LINN
  1003.     /* check also pointnet address */
  1004.     if (point==0) {
  1005.             for (i=0; i<nalias; i++)
  1006.             {
  1007.                     if (alias[i].zone==zone && alias[i].pointnet==net &&
  1008.                         alias[i].point==node) return 1;
  1009.             }
  1010.     }
  1011. #endif
  1012.         return 0;
  1013. }
  1014.  
  1015. int ReadMessage()
  1016. {
  1017.     *MESSAGE=0;
  1018.     if (fread((char *) &Mhdr, sizeof(struct Hdr), 1, MHDR)!=1) return -1;
  1019.     
  1020.     if (Mhdr.flags & DELETED) return 0;
  1021.     if (Mhdr.flags & SENT) return 0;
  1022.     if (Mhdr.mailer[0]) return 0;
  1023.     if (OurMessage(0)) return 0;
  1024.     if (Mhdr.Dnode==65535U || Mhdr.Dnet==65535U || Mhdr.Dzone==65535U) return 0;
  1025.  
  1026.     memcpy(&Shdr, &Mhdr, sizeof(struct Hdr));
  1027.     fseek(MMSG,Mhdr.Mstart,SEEK_SET);
  1028.     if (Mhdr.size > MAXMSGLEN) {
  1029.        message(6,"!Message too long (%u)",Mhdr.size);
  1030.        return (-1);
  1031.     }
  1032.  
  1033.     if (fread(MESSAGE, Mhdr.size, 1, MMSG)!=1)
  1034.     {
  1035.         message(6,"!Error reading message from file");
  1036.         return -1;
  1037.     }
  1038.     *(MESSAGE + Mhdr.size)= '\0';
  1039.  
  1040.     if (Mhdr.flags & MSGLOCAL) return 1;
  1041.     if (OurMessage(1)) return 0;
  1042.     if (ForwardOk(Mhdr.Ozone,Mhdr.Onet,Mhdr.Onode,Mhdr.Opoint,
  1043.                      Mhdr.Dzone,Mhdr.Dnet,Mhdr.Dnode,Mhdr.Dpoint,
  1044.                      Mhdr.flags & CRASH, Mhdr.flags & FILEATCH)) return 1;
  1045.     /* If we're not forwarding crashmail, then as normal mail?? */
  1046.     if (ForwardOk(Mhdr.Ozone,Mhdr.Onet,Mhdr.Onode,Mhdr.Opoint,
  1047.                      Mhdr.Dzone,Mhdr.Dnet,Mhdr.Dnode,Mhdr.Dpoint,
  1048.                      0, Mhdr.flags & FILEATCH))
  1049.     {
  1050.         Mhdr.flags &= ~CRASH;
  1051.         return 1;
  1052.     }
  1053.     return 0;
  1054. }
  1055.  
  1056. void SaveMessage()
  1057. {
  1058. #if DEBUG
  1059. print("SaveMessage\n");
  1060. #endif
  1061.     fseek(MHDR, ftell(MHDR) - (long) sizeof(struct Hdr), SEEK_SET);
  1062.     if (fwrite((char *) &Shdr, sizeof(struct Hdr), 1, MHDR)!=1)
  1063.     {
  1064.         message(6,"!Error writing message to file");
  1065.         exit(1);
  1066.     }
  1067.  
  1068.     /* Don't tell me this should do the job, I know, tell TC 2.0 (PC) */
  1069.     fflush(MHDR);
  1070.  
  1071.     /* But this never failed, so... */
  1072.     fseek(MHDR,ftell(MHDR),SEEK_SET);
  1073. }
  1074.  
  1075. void Destination(zone,net,node,type)
  1076. int *zone, *net, *node, *type;
  1077. {
  1078.     int i;
  1079.     int pzone, pnet, pnode;
  1080.  
  1081. /*
  1082.     *zone= Mhdr.Dzone;
  1083.     *net= Mhdr.Dnet;
  1084.     *node= Mhdr.Dnode;
  1085.     if (Mhdr.Dpoint!=0)
  1086.     {
  1087.         for (i=0; i<nalias; i++)
  1088.         {
  1089.             if (alias[i].zone== *zone && alias[i].net== *net &&
  1090.                 alias[i].node== *node && alias[i].point==0) break;
  1091.         }
  1092.         if (i<nalias)
  1093.         {
  1094.             *net=alias[i].pointnet;
  1095.             *node=Mhdr.Dpoint;
  1096.         }
  1097.     }
  1098. */
  1099. #ifdef LINN
  1100.     /* since Direct flag may not be set by some message editors,
  1101.        setting both Crash and Hold flags is equivalent */
  1102.     /* note that DIRECT flag (bit 10) is zeroed on importing, but not
  1103.        on exporting (best way ?) */
  1104.     if ((Mhdr.flags & (CRASH+MSGHOLD)) == CRASH+MSGHOLD) {
  1105.         Mhdr.flags |= DIRECT;
  1106.         Mhdr.flags -= CRASH+MSGHOLD;
  1107.     }
  1108. #endif
  1109.     ToWhere(zone,net,node,Mhdr.Dzone,Mhdr.Dnet,Mhdr.Dnode,Mhdr.Dpoint,
  1110. #ifdef LINN
  1111.             Mhdr.flags & (CRASH+DIRECT), Mhdr.flags & FILEATCH);
  1112. #else
  1113.             Mhdr.flags & CRASH, Mhdr.flags & FILEATCH);
  1114. #endif
  1115.  
  1116.     *type = Mhdr.flags & CRASH ? 'C' : Mhdr.flags & MSGHOLD ? 'H' : 'N';
  1117.  
  1118.     /* Remap if it's to one of our points and it's a packet to him/her */
  1119.     if (Mhdr.Dpoint!=0)
  1120.     {
  1121.         pzone= Mhdr.Dzone;
  1122.         pnet= Mhdr.Dnet;
  1123.         pnode= Mhdr.Dnode;
  1124.  
  1125.         for (i=0; i<nalias; i++)
  1126.         {
  1127.             if (alias[i].zone== pzone && alias[i].net== pnet &&
  1128.                 alias[i].node== pnode && alias[i].point== 0) break;
  1129.         }
  1130.         if (i<nalias)
  1131.         {
  1132.             pnet=alias[i].pointnet;
  1133.             pnode=Mhdr.Dpoint;
  1134.             if (pnode== *node && pnet== *net && pzone== *zone)
  1135.             {
  1136.                 /* It seems to be directly to our point, Pfew */
  1137.                 Mhdr.Dnode= pnode;
  1138.                 Mhdr.Dpoint= 0;
  1139.                 Mhdr.Dnet= pnet;
  1140.             }
  1141.         }
  1142.     }
  1143. }
  1144.  
  1145. void OpenPacket(nr,zone,net,node,type)
  1146. int nr, zone, net, node, type;
  1147. {
  1148.     struct time t;
  1149.     struct date d;
  1150.     struct _pkthdr phdr;
  1151.     char fname[80];
  1152.  
  1153. #if DEBUG
  1154. print("Open packet[%d] %d:%d/%d, type %c\n",nr,zone,net,node,type);
  1155. #endif
  1156.     /* Get password first before all information is destroyed */
  1157.     getalias(zone,net,node,0);
  1158.     get_passw(zone,net,node,0);
  1159.  
  1160. #ifdef LINN
  1161.     if (binkley)
  1162.         if (zone==alias[0].zone)
  1163.         sprint(fname, "%s%03z%03z00.%cPT", hold, net, node, binktype((char)type));
  1164.     else    sprint(fname, "%s.%03y%c%03z%03z00.%cPT", holdbink, zone, DIRSEP, net, node, binktype((char)type));
  1165.     else
  1166.     sprint(fname, "%s%02z%03z%03z.%cM", hold, zone, net, node, type);
  1167. #else
  1168.     sprint(fname, "%s%02z%03z%03z.%cM", hold, zone, net, node, type);
  1169. #endif
  1170.  
  1171.     pktzone[nr]= zone;
  1172.     pktnet[nr]= net;
  1173.     pktnode[nr]= node;
  1174.     pkttype[nr]= type;
  1175.  
  1176.     pktfile[nr]= fopen(fname,BRUP);
  1177.     if (pktfile[nr]!=NULL)
  1178.     {
  1179.         fseek(pktfile[nr],-2L,SEEK_END);
  1180.         return;
  1181.     }
  1182.  
  1183.     pktfile[nr]= fopen(fname,BWUP);
  1184.     if (pktfile[nr]==NULL)
  1185.     {
  1186.         message(6,"!Can't open file %s",fname);
  1187.         exit(1);
  1188.     }
  1189.  
  1190.     /* new packet, we've to make a header first */
  1191.     getdate(&d);
  1192.     gettime(&t);
  1193.     memset(&phdr, 0, sizeof(struct _pkthdr));
  1194.  
  1195.     /* are we a point and not to boss then re-address */
  1196.     if (ourpoint)
  1197.     {
  1198.         if (ournode!=node || ournet!=net || ourzone!=zone)
  1199.         {
  1200.             phdr.ph_onode= inteli(-1);
  1201.             phdr.ph_onet = inteli(ournet);
  1202.         }
  1203.         else
  1204.         {
  1205.             phdr.ph_onode= inteli(ourpoint);
  1206.             phdr.ph_onet= inteli(ourpointnet);
  1207.         }
  1208.     }
  1209.     else
  1210.     {
  1211.         phdr.ph_onode=inteli(ournode);
  1212.         phdr.ph_onet=inteli(ournet);
  1213.     }
  1214.     phdr.ph_ozone=inteli(ourzone);
  1215.     phdr.ph_dnode=inteli(node);
  1216.     phdr.ph_dnet=inteli(net);
  1217.     phdr.ph_dzone=inteli(zone);
  1218.     phdr.ph_yr=inteli(d.da_year);
  1219.     phdr.ph_mo=inteli(d.da_mon-1);
  1220.     phdr.ph_dy=inteli(d.da_day-1);
  1221.     phdr.ph_hr=inteli(t.ti_hour);
  1222.     phdr.ph_mn=inteli(t.ti_min);
  1223.     phdr.ph_sc=inteli(t.ti_sec);
  1224.     phdr.ph_rate=0;
  1225.     phdr.ph_ver=inteli(2);
  1226.     phdr.ph_prod=inteli(isBERMUDA);
  1227.     strncpy(phdr.ph_pwd,ourpwd,8);
  1228.     if( fwrite((char *)&phdr, sizeof(struct _pkthdr), 1, pktfile[nr]) !=1)
  1229.     {
  1230.         message(6,"-Write error (disk full??)");
  1231.         exit(1);
  1232.     }
  1233. }
  1234.  
  1235. int MakeMsg(nr)
  1236. int nr;
  1237. {
  1238.     struct _pktmsgs mh;
  1239. #ifndef LINN
  1240.     struct date d;
  1241.     struct time t;
  1242. #endif
  1243.     FILE *pkt= pktfile[nr];
  1244.     FILE *temp;
  1245.     int direct=0;
  1246.     char *p, *q;
  1247.     char files[80];
  1248.     char name[80];
  1249. #ifdef LINN
  1250.     char tmp[100];
  1251. #endif
  1252.     
  1253. #if DEBUG
  1254. print("MakeHdr\n");
  1255. #endif
  1256.     mh.pm_ver=inteli(2);
  1257.  
  1258. #ifdef LINN
  1259.     /* Change origin of netmail if needed */
  1260.     if (OurMessage(1))
  1261.     {
  1262. #if DEBUG
  1263. printf("origine %d:%d/%d.%d\n", Mhdr.Dzone, Mhdr.Dnet, Mhdr.Dnode, Mhdr.Dpoint);
  1264. #endif
  1265.         getalias(Mhdr.Dzone, Mhdr.Dnet, Mhdr.Dnode, 0 /* VP Mhdr.Dpoint*/);
  1266. #if DEBUG
  1267. printf("changed to %d:%d/%d.%d\n", ourzone, ournet, ournode, ourpoint);
  1268. #endif
  1269.         Mhdr.Ozone  = Shdr.Ozone  = ourzone;
  1270.         Mhdr.Onet   = Shdr.Onet   = ournet;
  1271.         Mhdr.Onode  = Shdr.Onode  = ournode;
  1272.         Mhdr.Opoint = Shdr.Opoint = ourpoint;
  1273.     }
  1274. #endif
  1275.  
  1276.     /* Get the correct ID, we might need it */
  1277.     getalias(pktzone[nr], pktnet[nr], pktnode[nr], 0);          /* ,0 by Agl */
  1278.  
  1279.     /* mail to boss or direct mail? */
  1280.     if (Mhdr.Opoint && OurMessage(1) &&
  1281.         (pktzone[nr]!=ourzone || pktnet[nr]!=ournet || pktnode[nr]!=ournode))
  1282.     {
  1283.         /* direct to other than BOSS --> re-addressing! */
  1284.         mh.pm_onode=inteli(ournode);
  1285.         mh.pm_onet=inteli(ournet);
  1286.         direct=1;
  1287.     }
  1288.     else
  1289.     {
  1290.         /* to BOSS (or normal BBS opperation) --> normal address */
  1291.         mh.pm_onode=inteli(Mhdr.Onode);
  1292.         mh.pm_onet=inteli(Mhdr.Onet);
  1293.     }
  1294.  
  1295.     mh.pm_dnode=inteli(Mhdr.Dnode);
  1296.     mh.pm_dnet=inteli(Mhdr.Dnet);
  1297.     if (Mhdr.Dzone && pktzone[nr] && (Mhdr.Dzone!=pktzone[nr]))
  1298.     {
  1299.         mh.pm_dnet=inteli(Mhdr.Ozone);
  1300.         mh.pm_dnode=inteli(Mhdr.Dzone);
  1301.     }
  1302.  
  1303.     mh.pm_attr=inteli(Mhdr.flags&0x3413);
  1304.     mh.pm_cost=inteli(Mhdr.cost);
  1305.     fwrite((char *)&mh, sizeof(struct _pktmsgs), 1, pkt);
  1306.     fprintf(pkt,"%19s",Mhdr.time);
  1307.     putc('\0',pkt);
  1308.     fprintf(pkt,"%s",Mhdr.to);        /* from & to */
  1309.     putc('\0',pkt);
  1310.     fprintf(pkt,"%s",Mhdr.from);
  1311.     putc('\0',pkt);
  1312.     
  1313.     if (verbose>1) message(1,"=%s (%d:%d/%d.%d) --> %s (%d:%d/%d.%d)",Mhdr.from,
  1314.         Mhdr.Ozone, Mhdr.Onet, Mhdr.Onode, Mhdr.Opoint,
  1315.         Mhdr.to, Mhdr.Dzone, Mhdr.Dnet, Mhdr.Dnode, Mhdr.Dpoint);
  1316.     
  1317.     if (Mhdr.flags&FILEATCH)
  1318.     {
  1319. #ifdef LINN
  1320.         if (binkley)
  1321.         if (pktzone[nr]==alias[0].zone)
  1322.             sprint(name, "%s%03z%03z00.%cFT", hold, pktnet[nr], pktnode[nr], binktype((char)pkttype[nr]));
  1323.         else    sprint(name, "%s.%03y%c%03z%03z00.%cFT", holdbink, pktzone[nr], DIRSEP, pktnode[nr], binktype((char)pkttype[nr]));
  1324.     else
  1325.         sprint( name,"%s%02z%03z%03z.%cF", hold, pktzone[nr],pktnet[nr],
  1326.            pktnode[nr],pkttype[nr]);
  1327. #else
  1328.         sprint( name,"%s%02z%03z%03z.%cF", hold, pktzone[nr],pktnet[nr],
  1329.            pktnode[nr],pkttype[nr]);
  1330. #endif
  1331.  
  1332.         if((temp=fopen(name,"a+"))==NULL && (temp=fopen(name,"w+"))==NULL)
  1333.         {
  1334.             message(6,"!!! Error opening file attaches: %s",name);
  1335.             message(6,"!!! for file(s): %s",Mhdr.topic);
  1336.             return -1;
  1337.         }
  1338.  
  1339.         strcpy(files,Mhdr.topic);
  1340.         q= files;
  1341.  
  1342.         while (*q)
  1343.         {
  1344.             p= q;
  1345.             /* Find end of filename */
  1346.             while (*q && !isspace(*q) && *q!=',') q++;
  1347.  
  1348.             if (*q)
  1349.             {
  1350.                 *q='\0';
  1351.                 q++;
  1352.             }
  1353.  
  1354.             /* to attach file (fix path if forwarding) */
  1355.             fprintf(temp, "%s%s\n",
  1356.                 (OurMessage(1) || (Mhdr.flags&MSGLOCAL)) ? "" : mailpath,
  1357.                 p);
  1358.  
  1359.             /* strip path */
  1360.             p= q-2;
  1361. #if UNIX
  1362.             while (p!=files && *p && *p!=':' && *p!='/') --p;
  1363.             if (!*p || *p==':' || *p=='/') ++p;
  1364. #else
  1365.             while (p!=files && *p && *p!=':' && *p!='\\') --p;
  1366.             if (!*p || *p==':' || *p=='\\') ++p;
  1367. #endif
  1368.  
  1369.             /* to message */
  1370.             fprintf(pkt,"%s ",p);         /* plain filename (no path) */
  1371.  
  1372.         /* display in logfile too */
  1373.             if (verbose>1) message(1,"= File %s",p);
  1374.         }
  1375.         fclose(temp);
  1376.     }
  1377.     else
  1378.     {
  1379.         fprintf(pkt,"%s",Mhdr.topic);     /* topic */
  1380.     }
  1381.     putc('\0',pkt);
  1382.     
  1383.     if (Mhdr.Ozone && Mhdr.Dzone && ((Mhdr.Ozone!=Mhdr.Dzone) || addintl))
  1384.         fprintf(pkt,"\01INTL %d:%d/%d %d:%d/%d\r\n", Mhdr.Dzone,
  1385.           Mhdr.Dnet, Mhdr.Dnode, Mhdr.Ozone, Mhdr.Onet, Mhdr.Onode);
  1386.     if (Mhdr.Dpoint!=0 && pktnet[nr]!=ourpointnet)
  1387.         fprintf(pkt,"\01TOPT %d\r\n",Mhdr.Dpoint);
  1388.  
  1389.     /* We do NOT allow points under points! (gives 2 kludge lines) */
  1390.     if (direct)
  1391.     {
  1392.         fprintf(pkt,"\01FMPT %d\r\n",ourpoint);
  1393.     }
  1394.     if (Mhdr.Opoint!=0)
  1395.         fprintf(pkt,"\01FMPT %d\r\n",Mhdr.Opoint);
  1396.  
  1397.     p= MESSAGE;
  1398.     while (*p)                            /* message */
  1399.     {
  1400.         if (*p=='\n') putc('\r',pkt);
  1401.         putc(*p,pkt);
  1402.         p++;
  1403.     }
  1404.  
  1405.     if (!OurMessage(1))
  1406.     {
  1407. #ifdef LINN
  1408.     /* display date in european (?) format */
  1409.     sprint (tmp, "\01Via Bermuda-P %s %d:%d/%d, $D $m $y at $T\r\n",
  1410.                 UVERSION, ourzone, ournet, ournode); 
  1411.         fprintf(pkt, tmp);
  1412. #else
  1413.         getdate(&d);
  1414.         gettime(&t);
  1415.         fprintf(pkt,"\r\n\01Via Node %d:%d/%d %02d:%02d %02d/%02d by BERMUDA-P %s\r\n",
  1416.                 ourzone, ournet, ournode, t.ti_hour, t.ti_min, d.da_mon, d.da_day, UVERSION);
  1417. #endif
  1418.     }
  1419.     putc('\0',pkt);                     /* terminator */
  1420.  
  1421.     Shdr.flags |= SENT;
  1422.     if (Shdr.flags & KILLSEND) Shdr.flags |= DELETED;
  1423.     return (0);
  1424. }
  1425.  
  1426. void PackTo(zone, net, node, type)
  1427. int zone, net, node, type;
  1428. {
  1429.         int i;
  1430.         int empty=-1;
  1431.         static int j=0;
  1432.  
  1433.         for (i=0; i<10; i++)
  1434.         {
  1435.                 if (pktfile[i]==NULL && empty==-1) empty=i;
  1436.                 if (zone==pktzone[i] && net==pktnet[i] &&
  1437.                     node==pktnode[i] && type==pkttype[i]) break;
  1438.         }
  1439.  
  1440.         if (i>=10)
  1441.         {
  1442.                 if (empty==-1)
  1443.                 {
  1444.                         ClosePacket(j);
  1445.                         i= j;
  1446.                         j= (j==9) ? 0 : j+1;
  1447.                 }
  1448.                 else i=empty;
  1449.                 OpenPacket(i,zone,net,node,type);
  1450.         }
  1451.  
  1452.         MakeMsg(i);
  1453. }
  1454.  
  1455. #ifdef LINN
  1456. int CallArc(archiver, comline, zone, net, node, type)
  1457. char *archiver, *comline;
  1458. int  zone, net, node, type;
  1459. {
  1460.     char newname[80];
  1461.     char arcname[80];
  1462.     char buffer[80];
  1463.     char cmd[128];
  1464.     char *buf;
  1465.     struct date d;
  1466.     struct time t;
  1467.     int result;
  1468.     FILE *fd;
  1469.  
  1470.     getdate(&d);
  1471.     gettime(&t);
  1472.  
  1473.     if (!archiver) {
  1474.         /* if undefined, compatibility */
  1475.         archiver=arc_prg;
  1476.         comline=arc_cmd;
  1477.     }
  1478.  
  1479.     if (binkley)
  1480.         if (zone==alias[0].zone) {
  1481.         sprint(buffer, "%s%03z%03z00.%cPT", hold, net, node, binktype((char)type));
  1482.         sprint(newname, "%s%02d%02d%02d%02d.PKT", hold, d.da_day, t.ti_hour, t.ti_min, t.ti_sec);
  1483.     } else {
  1484.         sprint(buffer, "%s.%03y%c%03z%03z00.%cPT", holdbink, zone, DIRSEP, net, node, binktype((char)type));
  1485.         sprint(newname, "%s.%03y%c%02d%02d%02d%02d.PKT", holdbink, zone, DIRSEP, d.da_day, t.ti_hour, t.ti_min, t.ti_sec);
  1486.     }
  1487.     else {
  1488.     sprint(buffer, "%s%02z%03z%03z.%cM", hold, zone, net, node, type);
  1489.     sprint(newname, "%s%02d%02d%02d%02d.PKT", hold, d.da_day, t.ti_hour, t.ti_min, t.ti_sec);
  1490.     }
  1491.  
  1492.     if (rename(buffer,newname)) {
  1493.         message(6,"!Fatal error renaming packet %s",buffer);
  1494.         exit(2);
  1495.     }
  1496.  
  1497.     /* Ok it has got a 'standard' name now, next step is finding
  1498.        an archive */
  1499.  
  1500.     if (binkley)
  1501.         if (zone==alias[0].zone)
  1502.         sprint(arcname, "%s%03z%03z00.%cAT", hold, net, node, binktype((char)type));
  1503.     else    sprint(arcname, "%s.%03y%c%03z%03z00.%cAT", holdbink, zone, DIRSEP, net, node, binktype((char)type));
  1504.     else
  1505.     sprint(arcname, "%s%02z%03z%03z.%cA", hold, zone, net, node, type);
  1506.  
  1507.  
  1508.     /* set up command line */
  1509.         buf=cmd+1;    /* copy to buffer2 the command line */
  1510.         while (*comline != '\0') {
  1511.             if (*comline != '%')
  1512.                 *buf++ = *comline++;
  1513.             else {
  1514.                 switch (*++comline) {
  1515.                     case 'p' : /* %p = packet */
  1516.                        strcpy (buf, newname);
  1517.                            buf = &buf[strlen(buf)];
  1518.                            break;
  1519.                     case 'n' : /* %n = archive name */
  1520.                        strcpy (buf, arcname);
  1521.                            buf = &buf[strlen(buf)];
  1522.                            break;
  1523.                     case 'd' : /* %d = hold path */
  1524.                            if ((binkley) && (zone != alias[0].zone))
  1525.                                sprint (buf, "%s.%03y%c", holdbink, zone, DIRSEP);
  1526.                            else
  1527.                         strcpy (buf, hold);
  1528.                            buf = &buf[strlen(buf)];
  1529.                            break;
  1530.                     case 'k' : /* %k = packet without path */
  1531.                        sprint(buf, "%02d%02d%02d%02d.PKT", d.da_day, t.ti_hour, t.ti_min, t.ti_sec);
  1532.                            buf = &buf[strlen(buf)];
  1533.                            break;
  1534.                        case '%' : *buf++ = *comline;
  1535.                               break;
  1536.                        case ':' : *buf++ = ';';
  1537.                               break;
  1538.                 }
  1539.                 if (*comline != '\0')
  1540.                     comline++;
  1541.             }
  1542.     }
  1543.         *buf='\0';
  1544.     *cmd= strlen(cmd+1);
  1545.  
  1546.      result = execute(archiver,cmd);
  1547.  
  1548.      if (result) {
  1549.         message(6,"!Error: Packet not ARCed.");
  1550.         rename(newname,buffer);
  1551.      }
  1552.      else {
  1553.          /* succeeded or trap? Check for file */
  1554.          if ((fd = fopen(newname,"r")) != NULL) {
  1555.             fclose(fd);
  1556.             rename(newname,buffer);
  1557.             message(6,"!Error: Packet not ARCed.");
  1558.              /* continue; */
  1559.          }
  1560.      }
  1561.      return (result);
  1562. }
  1563.  
  1564. void ArcMail()
  1565.    /* This Routine searches the outbound dir for mail packets and
  1566.        arcs them if needed. Calls ArcOk(zone,net,node) to check
  1567.        if the packet should be arced */
  1568. {
  1569.     char buffer[80];
  1570.     int zone, net, node;
  1571.     char *p;
  1572.     int type;
  1573.     int num_pktnames;
  1574.     int i, archiv;
  1575.     static char name[5][4]={"arc","zip","zoo","lzh","arj"};
  1576.     
  1577.     sprint(buffer, "%s*.?M", hold);
  1578.     for (num_pktnames = 0, p = ffirstout(buffer); p != NULL; p = fnextout()) {
  1579.         if ((pktnames[num_pktnames++] = strdup(p)) == NULL) {
  1580.            message(6,"!Mem error");
  1581.            exit (1);
  1582.         }
  1583.     }
  1584.  
  1585.     for (i = 0; i < num_pktnames; free(pktnames[i++])) {
  1586.         getadress(pktnames[i],&zone,&net,&node);
  1587.         type = pktnames[i][strlen(pktnames[i])-2];
  1588. #if DEBUG
  1589. message(6," ArcMail: found mail (%c) to %d:%d/%d",type,zone,net,node);
  1590. #endif
  1591.         if ((archiv=ArcOk(zone,net,node)) != -1) {
  1592.             message (1, "+Node %d:%d/%d gets %smail",zone,net,node,name[archiv]);
  1593.             CallArc (archiv_prg[archiv],archiv_cmd[archiv],zone,net,node,type);
  1594.         }
  1595.      }
  1596. }
  1597. #else    /* !LINN */
  1598. void ArcMail()
  1599. {
  1600.     /* This Routine searches the outbound dir for mail packets and
  1601.        arcs them if needed. Calls ArcOk(zone,net,node) to check
  1602.        if the packet should be arced */
  1603.  
  1604.     char buffer[80];
  1605.     char newname[80];
  1606.     char arcname[80];
  1607.     char cmd[128];
  1608.     int zone, net, node;
  1609.     char *p;
  1610.     struct date d;
  1611.     struct time t;
  1612.     int type;
  1613.     int result;
  1614.     FILE *fd;
  1615.     int num_pktnames;
  1616.     int i;
  1617.  
  1618.     sprint(buffer, "%s*.?M", hold);
  1619.     for (num_pktnames = 0, p = ffirst(buffer); p != NULL; p = fnext()) {
  1620.         if ((pktnames[num_pktnames++] = strdup(p)) == NULL) {
  1621.            message(6,"!Mem error");
  1622.            exit (1);
  1623.         }
  1624.     }
  1625.  
  1626.     for (i = 0; i < num_pktnames; free(pktnames[i++])) {
  1627.         getadress(pktnames[i],&zone,&net,&node);
  1628.         type = pktnames[i][strlen(pktnames[i])-2];
  1629. #if DEBUG
  1630. message(6," ArcMail: found mail (%c) to %d:%d/%d",type,zone,net,node);
  1631. #endif
  1632.         if (ArcOk(zone,net,node)) {
  1633.            getdate(&d);
  1634.            gettime(&t);
  1635.            sprint(buffer,  "%s%02z%03z%03z.%cM",
  1636.                   hold, zone, net, node, type);
  1637.            sprint(newname, "%s%02d%02d%02d%02d.PKT", hold,
  1638.                   d.da_day, t.ti_hour, t.ti_min, t.ti_sec);
  1639. #if DEBUG
  1640. print("New packet-name: %s\n",newname);
  1641. #endif
  1642.            if (rename(buffer,newname)) {
  1643.               message(6,"!Fatal error renaming packet %s",buffer);
  1644.               exit(2);
  1645.            }
  1646.  
  1647.            /* Ok it has got a 'standard' name now, next step is finding
  1648.               an archive */
  1649.            sprint(arcname, "%s%02z%03z%03z.%cA",
  1650.                            hold, zone, net, node, type);
  1651.  
  1652.            /* Now call ARC! */
  1653.            /* ARC M B:\MAIL\00000001.NA B:\02010101.PKT             */
  1654.            sprint((cmd+1), "%s %s %s", arc_cmd, arcname, newname);
  1655.            *cmd= strlen(cmd+1);
  1656.  
  1657. #if DEBUG
  1658. print(">>%s %s<<",arc_prg,(cmd+1));
  1659. #endif
  1660.            result = execute(arc_prg,cmd);
  1661.  
  1662. #if DEBUG
  1663. print("Arc result: %d\n",result);
  1664. #endif
  1665.            if (result) {
  1666.               message(6,"!Error: Packet not ARCed.");
  1667.               rename(newname,buffer);
  1668.            }
  1669.            else {
  1670.               /* succeeded or trap? Check for file */
  1671.               if ((fd = fopen(newname,"r")) != NULL) {
  1672.                  fclose(fd);
  1673.                  rename(newname,buffer);
  1674.                  message(6,"!Error: Packet not ARCed.");
  1675.                  continue;
  1676.               }
  1677.            }     /*arc succeeded*/
  1678.         }
  1679.      }
  1680. }
  1681. #endif /* LINN */
  1682.  
  1683. void ReDirect()
  1684. {
  1685.     int zone, net, node;
  1686.     int dzone, dnet, dnode;
  1687.     char buffer[80];
  1688.     char *p;
  1689.     FILE *fd;
  1690.     int ch, type;
  1691.     int i, num_pktnames;
  1692.  
  1693.     sprint(buffer, "%s*.?M", hold);
  1694.     for (num_pktnames = 0, p = ffirstout(buffer); p != NULL; p = fnextout()) {
  1695.         if ((pktnames[num_pktnames++] = strdup(p)) == NULL) {
  1696.            message(6,"!Mem error");
  1697.            exit (1);
  1698.         }
  1699.     }
  1700.  
  1701.     for (i = 0; i < num_pktnames; free(pktnames[i++])) {
  1702.         getadress(pktnames[i],&zone,&net,&node);
  1703.         type = pktnames[i][strlen(pktnames[i])-2];
  1704. #if DEBUG
  1705. message(6," Redirect: found mail (%c) to %d:%d/%d",type,zone,net,node);
  1706. #endif
  1707.         dzone = zone;
  1708.         dnet  = net;
  1709.         dnode = node;
  1710.         ReDirectTo(&zone, &net, &node, dzone, dnet, dnode, type == 'C');
  1711.         if (zone != dzone || net != dnet || node != dnode) {
  1712. #if DEBUG
  1713. message(6," ReDirect: should sent to %d:%d/%d", zone,net,node);
  1714. #endif
  1715. #ifdef LINN
  1716.     if (binkley)
  1717.             if (zone==alias[0].zone)
  1718.             sprint(buffer, "%s%03z%03z00.%cPT", hold, net, node, binktype((char)type));
  1719.         else    sprint(buffer, "%s.%03y%c%03z%03z00.%cPT", holdbink, zone, DIRSEP, net, node, binktype((char)type));
  1720.     else
  1721.         sprint(buffer, "%s%02z%03z%03z.%cM", hold, zone, net, node, type);
  1722. #else
  1723.             sprint(buffer,  "%s%02z%03z%03z.%cM",
  1724.                    hold, zone, net, node, type);
  1725. #endif
  1726.             OpenPacket(0,zone,net,node,type);
  1727.  
  1728.             /* We've a new packet open (to real destination) */
  1729.             fd = fopen(buffer,BRUP);
  1730.             if (fd == NULL) {
  1731.                message(6,"!Can't open %s",buffer);
  1732.                exit(1);
  1733.             }
  1734.             fseek(fd, (long) sizeof(struct _pkthdr), SEEK_SET);
  1735.  
  1736.             /* start copying data now */
  1737.             while ((ch = getc(fd)) != EOF) putc(ch,pktfile[0]);
  1738.             fclose(fd);
  1739.  
  1740.             /* Get to the correct position for EOF markers */
  1741.             fseek(pktfile[0],-2L,SEEK_END);
  1742.             ClosePacket(0);
  1743.  
  1744.             /* Now the data is copied we can get rid of the original */
  1745.             if (unlink(buffer)) {
  1746.                message(6,"!Can't delete %s",buffer);
  1747.                exit(1);
  1748.             }
  1749.         }
  1750.     }
  1751. }
  1752.  
  1753. void Hold()
  1754. {
  1755.     int zone, net, node;
  1756.     char buffer[80];
  1757.     char buffer1[80];
  1758.     char *p;
  1759.     int type;
  1760.     int num_pktnames;
  1761.     int i;
  1762.  
  1763.     sprint(buffer, "%s*.N?", hold);
  1764.     for (num_pktnames = 0, p = ffirstout(buffer); p != NULL; p = fnextout()) {
  1765.         if ((pktnames[num_pktnames++] = strdup(p)) == NULL) {
  1766.            message(6,"!Mem error");
  1767.            exit (1);
  1768.         }
  1769.     }
  1770.  
  1771.     for (i = 0; i < num_pktnames; free(pktnames[i++])) {
  1772.         getadress(pktnames[i],&zone,&net,&node);
  1773.         type = pktnames[i][strlen(pktnames[i])-1];
  1774. #if DEBUG
  1775. message(6," Hold: found (%c) to %d:%d/%d",type,zone,net,node);
  1776. #endif
  1777.  
  1778.         if (HoldOk(zone,net,node)) {
  1779. #if DEBUG
  1780. message(6," Hold: should hold for %d:%d/%d", zone,net,node);
  1781. #endif
  1782.  
  1783. #ifdef LINN
  1784.     if (binkley)
  1785.             if (zone==alias[0].zone) {
  1786.             sprint(buffer, "%s%03z%03z00.O%cT", hold, net, node, (type=='M') ? 'P' : type);
  1787.             sprint(buffer1, "%s%03z%03z00.H%cT", hold, net, node, (type=='M') ? 'P' : type);
  1788.         } else {
  1789.             sprint(buffer, "%s.%03y%c%03z%03z00.O%cT", holdbink, zone, DIRSEP, net, node, (type=='M') ? 'P' : type);
  1790.             sprint(buffer1, "%s.%03y%c%03z%03z00.H%cT", holdbink, zone, DIRSEP, net, node, (type=='M') ? 'P' : type);
  1791.         }
  1792.     else {
  1793.             sprint(buffer, "%s%02z%03z%03z.N%c", hold, zone, net, node, type);
  1794.         sprint(buffer1,"%s%02z%03z%03z.W%c", hold, zone, net, node, type);
  1795.     }
  1796. #else
  1797.            sprint(buffer, "%s%02z%03z%03z.N%c",
  1798.                           hold, zone, net, node, type);
  1799.            sprint(buffer1,"%s%02z%03z%03z.W%c",
  1800.                           hold, zone, net, node, type);
  1801. #endif
  1802.            if (rename(buffer,buffer1)) {
  1803.               message(6,"!Can't rename %s to %s",buffer,buffer1);
  1804.               exit(1);
  1805.            }
  1806.         }
  1807.     }
  1808. }
  1809.  
  1810. void UnHold()
  1811. {
  1812.     int zone, net, node;
  1813.     char buffer[80];
  1814.     char buffer1[80];
  1815.     char *p;
  1816.     int type;
  1817.     int num_pktnames;
  1818.     int i;
  1819.  
  1820.     sprint(buffer, "%s*.W?", hold);
  1821.     for (num_pktnames = 0, p = ffirstout(buffer); p != NULL; p = fnextout()) {
  1822.         if ((pktnames[num_pktnames++] = strdup(p)) == NULL) {
  1823.            message(6,"!Mem error");
  1824.            exit (1);
  1825.         }
  1826.     }
  1827.  
  1828.     for (i = 0; i < num_pktnames; free(pktnames[i++])) {
  1829.         getadress(pktnames[i],&zone,&net,&node);
  1830.         type = pktnames[i][strlen(pktnames[i])-1];
  1831. #if DEBUG
  1832. message(6," UnHold: found (%c) to %d:%d/%d",type,zone,net,node);
  1833. #endif
  1834.  
  1835.         if (type != 'F') {
  1836. #if DEBUG
  1837. message(6," UnHold: should unhold for %d:%d/%d", zone,net,node);
  1838. #endif
  1839. #ifdef LINN
  1840.        if (binkley)
  1841.             if (zone==alias[0].zone) {
  1842.             sprint(buffer, "%s%03z%03z00.H%cT", hold, net, node, (type=='M') ? 'P' : type);
  1843.             sprint(buffer1, "%s%03z%03z00.O%cT", hold, net, node, (type=='M') ? 'P' : type);
  1844.         } else {
  1845.             sprint(buffer, "%s.%03y%c%03z%03z00.H%cT", holdbink, zone, DIRSEP, net, node, (type=='M') ? 'P' : type);
  1846.             sprint(buffer1, "%s.%03y%c%03z%03z00.O%cT", holdbink, zone, DIRSEP, net, node, (type=='M') ? 'P' : type);
  1847.         }
  1848.        else {
  1849.             sprint(buffer, "%s%02z%03z%03z.W%c", hold, zone, net, node, type);
  1850.         sprint(buffer1,"%s%02z%03z%03z.N%c", hold, zone, net, node, type);
  1851.        }
  1852. #else
  1853.            sprint(buffer,  "%s%02z%03z%03z.W%c",
  1854.                            hold, zone, net, node, type);
  1855.            sprint(buffer1, "%s%02z%03z%03z.N%c",
  1856.                            hold, zone, net, node, type);
  1857. #endif
  1858.            if (rename(buffer,buffer1)) {
  1859.               message(6,"!Can't rename %s to %s",buffer,buffer1);
  1860.               exit(1);
  1861.            }
  1862.         }
  1863.     }
  1864. }
  1865.  
  1866.  
  1867. void MakePoll()
  1868. {
  1869.         int i=-1;
  1870.         char *p, *q;
  1871.         int zone, net, node;
  1872.         FILE *fd;
  1873.         char name[80];
  1874.  
  1875.         while ((p = PollNode(&i)) != NULL)
  1876.         {
  1877.                 if ((q = strchr(p,'.')) != NULL)
  1878.                 {
  1879.                         zone= alias[0].zone;
  1880.                         net = alias[0].pointnet;
  1881.                         node= atoi(q+1);
  1882.                         if (node==0)
  1883.                         {
  1884.                                 message(6,"-Invalid point (%s) in POLL",p);
  1885.                                 continue;
  1886.                         }
  1887.                 }
  1888.                 else
  1889.                 {
  1890.                     if (sscanf(p,"%d:%d/%d",&zone,&net,&node)!=3)
  1891.                     {
  1892.                         zone= alias[0].zone;
  1893.                         if (sscanf(p,"%d/%d",&net,&node)!=2)
  1894.                         {
  1895.                             net= alias[0].net;
  1896.                             node= atoi(p);
  1897.                             if (node==0)
  1898.                             {
  1899.                                 message(6,"-Invalid node (%s) in POLL",p);
  1900.                                 continue;
  1901.                             }
  1902.                         }
  1903.                     }
  1904.                 }
  1905. #ifdef LINN
  1906.         if (binkley)
  1907.             if (zone==alias[0].zone)
  1908.                 sprint(name, "%s%03z%03z00.OFT", hold, net, node);
  1909.             else    sprint(name, "%s.%03y%c%03z%03z00.OFT", holdbink, zone, DIRSEP, net, node);
  1910.         else    sprint(name,"%s%02z%03z%03z.PF",hold,zone,net,node);
  1911. #else
  1912.                 sprint(name,"%s%02z%03z%03z.PF",hold,zone,net,node);
  1913. #endif
  1914.                 fd= fopen(name,"a");
  1915.                 if (fd==NULL)
  1916.                 {
  1917.                     message(6,"!Could not create file %s",name);
  1918.                     exit(1);
  1919.                 }
  1920.                 fclose(fd);
  1921.         }
  1922. }
  1923.  
  1924. void DeInit()
  1925. {
  1926.         /* Don't know what to do here, but this way main is nice symetrical */
  1927. }
  1928.  
  1929. #if STTC
  1930. char *environ;
  1931.  
  1932. void main(argc, argv, envir)
  1933. int argc;
  1934. char *argv[], *envir;
  1935. #else
  1936. void main(argc, argv)
  1937. int argc;
  1938. char *argv[];
  1939. #endif
  1940. {
  1941.         int result, nrmsgs;
  1942.         int zone, net, node, type;
  1943.  
  1944. #if STTC
  1945.     environ= envir;
  1946. #endif
  1947.  
  1948.         /* Tell them who we are */
  1949.         fprintf(stderr,
  1950.          "BERMUDA : FidoNet compatible message processing software\n");
  1951.         fprintf(stderr,
  1952.          "PACK utility ; Version %s created %s at %s\n\n",UVERSION,
  1953.          __DATE__,__TIME__);
  1954.         fflush(stderr);
  1955.  
  1956.         /* Init first, parses commandline and configuration */
  1957.         Init(argc,argv);
  1958.         parse_route();
  1959.         nrmsgs=0;
  1960.  
  1961.         message(0,"+Unhold packets");
  1962.         /* Check for HOLD packets */
  1963.         UnHold();
  1964.  
  1965.         /* Open mail-area next */
  1966.         OpenMail();
  1967.  
  1968.         /* Init all packets (none open) */
  1969.         InitPackets();
  1970.  
  1971.         /* for all messages do
  1972.            begin
  1973.              read message;
  1974.              find destination;
  1975.              pack to destination;
  1976.            end;
  1977.          */
  1978.         message(2,"+Pack messages");
  1979.         while ((result=ReadMessage())!=-1)
  1980.         {
  1981.                 if (result)
  1982.                 {
  1983.                         Destination(&zone,&net,&node,&type);
  1984.                         PackTo(zone,net,node,type);
  1985.                         SaveMessage();
  1986.                         nrmsgs++;
  1987.                 }
  1988.         }
  1989.  
  1990.         /* DeInit packets (some might be open) */
  1991.         DeInitPackets();
  1992.  
  1993.         /* Get rid of the mail area */
  1994.         CloseMail();
  1995.  
  1996.         message(0,"+Redirect packets");
  1997.         /* If there are any redirections, do them now */
  1998.         ReDirect();
  1999.  
  2000.         message(0,"+Arc mail");
  2001.         /* Arc all mail found in the outbound directory */
  2002.         ArcMail();
  2003.  
  2004.         message(0,"+Hold mail");
  2005.         Hold();
  2006.  
  2007.         /* Anyone in for polling? */
  2008.         message(0,"+Prepare poll");
  2009.         MakePoll();
  2010.  
  2011.         /* DeInit program */
  2012.         DeInit();
  2013.  
  2014.         /* Tell them what we did */
  2015.         message(2,"+Processed %d messages",nrmsgs);
  2016.  
  2017. }
  2018.